package com.kfpanda.spring.batch.incrementer.h2;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameter;
import org.springframework.batch.core.JobParameters;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.stereotype.Repository;

import com.kfpanda.spring.batch.incrementer.AbstractJdbcIncrement;
import com.kfpanda.spring.batch.incrementer.Incrementer;
import com.kfpanda.spring.batch.incrementer.JdbcIncrement;

@Repository("h2JdbcIncrement")
public class H2JdbcIncrement extends AbstractJdbcIncrement implements JdbcIncrement<H2IncrementBean> {
	
	private final String INCREMENT_QUERY = "SELECT ID, incrementer, saveTime, updateTime, "
		+ "beforeIncrementer, incremType, incremName FROM INCREMENT ";
	private final String INCREMENT_UPDATE = "UPDATE INCREMENT SET incrementer=?, " 
		+ "beforeIncrementer=?, updateTime=SYSDATE ";
	private String incrementQuery = INCREMENT_QUERY;
	private String incrementUpdate = INCREMENT_UPDATE;

	public String preparedSql(String sql, Map<String, Object> paramMap){
		if(paramMap.isEmpty()){
			return sql;
		}
		sql += " WHERE ";
		for( Iterator<Entry<String, Object>> itr = paramMap.entrySet().iterator(); 
							itr.hasNext(); ){
			Entry<String, Object> entry = itr.next();
			sql += entry.getKey() + "='" + entry.getValue() +"' and ";
		}
		sql += " 1=1 ";
		return sql;
	}
	
	/*public H2IncrementBean queryIncrement(String sql, Map<String, Object> paramMap){
		sql = preparedSql(sql, paramMap);
		try{
			List<H2IncrementBean> result = getJdbcTemplate().query(sql, new H2IncrementBeanRowMapper());
			if (result.size() > 0 ) {
				return result.get(0);
			}else {
				throw new DataAccessResourceFailureException("increment query did not return a result");
			}
		}catch(Exception ex){
			throw new DataAccessResourceFailureException("Could not obtain increment value", ex);
		}
	}*/
	
	public String preparedWhere(JobParameters parameters){
		Map<String, Object> paramMap = new HashMap<String, Object>();
		Map<String, JobParameter> jobParams = parameters.getParameters();
    	for( Iterator<Entry<String, JobParameter>> itr = jobParams.entrySet().iterator(); 
    			itr.hasNext(); ){
    		Entry<String, JobParameter> entry = itr.next();
    		if(entry.getKey().startsWith(Incrementer.INCREMENTER_PREX)){
	    		JobParameter param = entry.getValue();
	    		//去掉前缀
	    		String key = entry.getKey().replace(Incrementer.INCREMENTER_PREX, "");
	    		paramMap.put(key, param.getValue());
    		}
    	}
    	String where = preparedSql("", paramMap);
    	return where;
	}
	
	@Override
	public H2IncrementBean findIncrementer(JobParameters parameters) {
		String where = preparedWhere(parameters);
		String sql = getIncrementQuery() + where;
		try{
			List<H2IncrementBean> result = getJdbcTemplate().query(sql, new H2IncrementBeanRowMapper());
			if (result.size() > 0 ) {
				return result.get(0);
			}else {
				throw new DataAccessResourceFailureException("increment query did not return a result");
			}
		}catch(Exception ex){
			throw new DataAccessResourceFailureException("Could not obtain increment value", ex);
		}
	}

	@Override
	public void updateIncrementer(JobExecution jobExecution) {
		Object increm = jobExecution.getExecutionContext().get(Incrementer.INCREMENTER_NAME);
		String incrementer = (increm == null) ? null : increm.toString();
		JobParameters parameters = jobExecution.getJobInstance().getJobParameters();
		H2IncrementBean incremBean = (H2IncrementBean) this.findIncrementer(parameters);
		incremBean.setBeforeIncrementer(parameters.getString(Incrementer.INCREMENTER_NAME));
		incremBean.setIncrementer(incrementer);
		
		String where = preparedWhere(parameters);
		String sql = getIncrementUpdate() + where;
		getJdbcTemplate().update(sql, new Object[]{incremBean.getIncrementer(), 
				incremBean.getBeforeIncrementer()});
	}
	
	public String getIncrementQuery() {
		return incrementQuery;
	}

	public void setIncrementQuery(String incrementQuery) {
		this.incrementQuery = incrementQuery;
	}

	public String getIncrementUpdate() {
		return incrementUpdate;
	}

	public void setIncrementUpdate(String incrementUpdate) {
		this.incrementUpdate = incrementUpdate;
	}
}
